package com.kate.mall.product.controller;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.TimeUnit;

//import org.apache.shiro.authz.annotation.RequiresPermissions;
import com.kate.mall.common.utils.RedisUtils;
import com.kate.mall.product.queue.GoodsSpecificationRefreshCacheRequest;
import com.kate.mall.product.queue.GoodsSpecificationUpdateDBRequest;
import com.kate.mall.product.service.impl.GoodsSpecificationServiceSyncImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
import com.kate.mall.product.entity.GoodsSpecificationEntity;
import com.kate.mall.product.service.GoodsSpecificationService;
import com.kate.mall.common.utils.PageUtils;
import com.kate.mall.common.utils.R;
import io.swagger.annotations.Api;

import javax.annotation.Resource;


/**
 * 商品规格表
 *
 * @author kate-chan
 * @email 857782993@qq.com
 * @date 2022-12-06 23:21:04
 */
@Api(tags = "GoodsSpecificationController", description = "商品规格表服务")
@RestController
@RequestMapping("product/goodsspecification")
@Slf4j
public class GoodsSpecificationController {
    @Autowired
    private GoodsSpecificationService goodsSpecificationService;

    @Resource
    private GoodsSpecificationServiceSyncImpl goodsSpecificationServiceSync;

    @Resource
    private RedisUtils redisUtils;

    /**
     * 列表
     */
    @GetMapping("/list")
    //@RequiresPermissions("product:goodsspecification:list")
    @ApiOperation("获取所有商品规格表信息")
    public R list(@RequestParam(required = false) Map<String, Object> params){
        PageUtils page = goodsSpecificationService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @GetMapping("/info/{id}")
    //@RequiresPermissions("product:goodsspecification:info")
    @ApiOperation("获取指定id的商品规格表详情")
    public R info(@PathVariable("id") Integer id) throws InterruptedException {
        //以前的方式：直接从数据库中读取
//		GoodsSpecificationEntity goodsSpecification = goodsSpecificationService.getById(id);
        //先去去排队，保障读写的顺序
        log.info("=======1.读：获取指定规格的详情==========");
//       GoodsSpecificationEntity goodsSpecification=goodsSpecificationService.getById(id);
        //TODO 1.创建刷新缓存的请求
        GoodsSpecificationRefreshCacheRequest refreshCacheRequest =
                new GoodsSpecificationRefreshCacheRequest(goodsSpecificationService,id);
        goodsSpecificationServiceSync.addRequest(refreshCacheRequest);

        long start = System.currentTimeMillis();
        GoodsSpecificationEntity goodsSpecification = null;
        while(true){//自旋
            long end = System.currentTimeMillis();
            if(end-start>200){
                log.info("=====读请求自旋获取数据失败......");
                break;//自旋超时，则执行兜底方案
            }
            //从redis缓存中读取指定id的商品的规格信息

            goodsSpecification = redisUtils.<GoodsSpecificationEntity>get("goods-service:spec:" + id,GoodsSpecificationEntity.class);
            log.info("====读请求自旋，从【缓存】中查询数据：{}",goodsSpecification);
            if(goodsSpecification==null){//缓存未命中
                //暂停20ms
                try {
                    TimeUnit.MICROSECONDS.sleep(20);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
            }else{//缓存命中
                break;
            }
        }
        if(goodsSpecification==null){//兜底方法
            goodsSpecification = goodsSpecificationService.refreshCache(id);
            log.info("====读请求自旋失败，兜底从【数据】中查询数据更缓存：{}",goodsSpecification);
        }
        return R.ok().put("goodsSpecification", goodsSpecification);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    @ApiOperation("添加商品规格表信息")
    //@RequiresPermissions("product:goodsspecification:save")
    public R save(@RequestBody GoodsSpecificationEntity goodsSpecification){
		goodsSpecificationService.save(goodsSpecification);

        return R.ok();
    }

    /**
     * 修改
     */
    @PutMapping("/update")
    @ApiOperation("更新指定id商品规格表信息")
    //@RequiresPermissions("product:goodsspecification:update")
    public R update(@RequestBody GoodsSpecificationEntity goodsSpecification) throws InterruptedException {
        //以前的方式：更新商品的规格值，直接更新数据库
//		goodsSpecificationService.updateById(goodsSpecification);
//        现在的方式：更新商品的规格值之前，先删除缓存， 然后再去更新数据
        //TODO 1.创建关联缓存的更新的请求
        log.info("=======1.写：从【数据库】更新数据规格信息==========");
        GoodsSpecificationUpdateDBRequest updateDBRequest =
                new GoodsSpecificationUpdateDBRequest(goodsSpecification,goodsSpecificationService);
        goodsSpecificationServiceSync.addRequest(updateDBRequest);

        return R.ok();
    }

    /**
     * 删除
     */
    @DeleteMapping("/delete")
    @ApiOperation("删除指定id商品规格表信息")
    //@RequiresPermissions("product:goodsspecification:delete")
    public R delete(@RequestBody Integer[] ids){
		goodsSpecificationService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

}
